package com.codi.bus.core.service.impl;

import com.codi.base.util.DateUtil;
import com.codi.base.util.DateUtils;
import com.codi.base.util.EqualsUtil;
import com.codi.base.util.ListUtil;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.constant.RuleConstant;
import com.codi.bus.core.dao.*;
import com.codi.bus.core.domain.*;
import com.codi.bus.core.dto.EventMsg;
import com.codi.bus.core.event.EventBusService;
import com.codi.bus.core.event.EventTypeDef;
import com.codi.bus.core.event.model.BaseEvent;
import com.codi.bus.core.fund.dao.FundPortfolioTransferDao;
import com.codi.bus.core.fund.domain.FundPortfolioTransfer;
import com.codi.bus.core.resultModel.*;
import com.codi.bus.core.service.*;
import com.codi.bus.core.service.model.ApplyModel;
import com.codi.bus.core.service.model.DividendModel;
import com.codi.bus.core.service.util.HundsunUtils;
import com.codi.bus.core.service.util.ModelPopulateUtils;
import com.codi.bus.core.vo.PortfolioTransferStatusVo;
import com.codi.bus.core.vo.TradePortfolioStatusVo;
import com.codi.bus.core.vo.TradeStatusVo;
import com.codi.bus.core.vo.query.OrderFundQueryVo;
import com.codi.bus.core.vo.query.PortfolioFundOrderQueryVo;
import com.codi.bus.exception.BaseException;
import com.codi.fcloud.ufx.constant.HsConst;
import com.codi.trade.dto.HsDividendQryDto;
import com.codi.trade.dto.HsTradeConfirmQryDto;
import com.codi.trade.dto.PortfolioSummaryQryDto;
import com.codi.trade.dto.TradeApplyQryDto;
import com.codi.trade.response.HsPortfolioSummaryQryResponse;
import com.codi.trade.response.HsTradeApplyQryResponse;
import com.codi.trade.response.HsTradeConfirmQryResponse;
import com.codi.trade.service.DividendsQueryService;
import com.codi.trade.service.TradeApplyQueryService;
import com.codi.trade.service.TradeConfirmQueryService;
import com.codi.trade.service.portfolio.HsPortfolioSummaryQryService;
import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.*;

/**
 * 模块名
 *
 * @author spy
 * @version 1.0 2017-12-18 13:58
 * @since 1.0
 */
@Slf4j
@Service
public class TradeSyncServiceImpl implements TradeSyncService {

    @Autowired
    private TradeOrderDao tradeOrderDao;

    @Autowired
    private OrderFundDao orderFundDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private PortfolioFundOrderDao portfolioFundOrderDao;

    @Autowired
    private FundPortfolioTransferDao fundPortfolioTransferDao;

    @Autowired
    private PortfolioService portfolioService;

    @Autowired
    private WorkingDateService workingDateService;

    @Autowired
    private TradeConfirmQueryService tradeConfirmQueryService;

    @Autowired
    private TradeService tradeService;

    @Autowired
    private EventBusService eventBusService;

    @Autowired
    private TradeApplyQueryService tradeApplyQueryService;

    @Autowired
    private UserService userService;

    @Autowired
    private HsPortfolioSummaryQryService hsPortfolioSummaryQryService;

    @Autowired
    private PortfolioTransferService portfolioTransferService;

    @Autowired
    private DividendsQueryService dividendsQueryService;

    @Autowired
    private UserMsgDao userMsgDao;

    @Autowired
    private LookupDao lookupDao;

    @Autowired
    private FundDetailService fundDetailService;

    @Autowired
    private MessageService messageService;



    @Override
    public void syncHundsun() {
        WorkingDayResult workingDayResult = workingDateService.getLastWorkingDay(new Date());

        if (workingDayResult.getSuccess()) {
            syncHundsun(workingDayResult.getLastWorkingDay());
            return;
        }

        log.error("fail to sync hundsun trader order status");
    }

    @Override
    public void syncHundsun(Date workDay) {
        log.info("working date={}", workDay);

        // 15天之内的交易记录
        Date beginCreateDate = DateUtil.getStartTime(DateUtils.addDay(workDay, -15));
        Date dividendBeginDate = DateUtil.getStartTime(workDay);
        Date endCreateDate = DateUtil.getEndTime(workDay);


        log.info("sync time is {}-->{}", beginCreateDate, endCreateDate);

        Stopwatch stopWatch = Stopwatch.createStarted();

        syncCommonFund(beginCreateDate, endCreateDate);

        syncPortfolioFund(beginCreateDate, endCreateDate);

        syncPortfolioTransfer(beginCreateDate, endCreateDate);

        syncDividend(dividendBeginDate, endCreateDate);

        syncFix(dividendBeginDate, endCreateDate);

        stopWatch.stop();

        log.info("sync hundsun all cost={}ms", stopWatch.elapsed(TimeUnit.MILLISECONDS));
    }

    private void syncCommonFund(Date beginCreateDate, Date endCreateDate) {
        log.info("sync common fund status");

        Stopwatch stopwatch = Stopwatch.createStarted();

        // 分页查询
        OrderFundQueryVo queryVo = OrderFundQueryVo.builder()
                                                   .fundStatus(GlobalConstant.FUND_STATUS_AWAITING_CONFIRM)
                                                   .beginCreateDate(beginCreateDate)
                                                   .endCreateDate(endCreateDate)
                                                   .build();



        TradeStatusVo statusVo;
        BaseEvent event;
        Map<String, String> eventMsgMap;



        List<OrderFund> orderFunds = orderFundDao.query(queryVo);
        if (orderFunds == null || orderFunds.isEmpty()) {
            return;
        }


        Iterator<OrderFund> iterator = orderFunds.iterator();

        while (iterator.hasNext()) {
            OrderFund orderFund = iterator.next();


            TradeOrder tradeOrder = tradeOrderDao.getEntityByOrderId(orderFund.getOrderId());


            User user = userDao.getEntity(tradeOrder.getUserId());

            String applyNo = orderFund.getExternalApplyNo();

            //String fundCode = orderFund.getFundCode();

            //FundDetail fundDetail = fundDetailService.getFundDetail(fundCode);

            HsTradeConfirmQryDto qryDto = HsTradeConfirmQryDto.builder()
                .client_id(user.getExternalClientId())
                .allot_no(applyNo)
                .build();

            List<HsTradeConfirmQryResponse> hsTradeList = null;
            try {
                hsTradeList = tradeConfirmQueryService.query(qryDto);
            } catch (Exception e) {
                log.error("fail to call hs trade confirm query service ", e);
                continue;
            }

            if (hsTradeList == null || hsTradeList.isEmpty()) {

                log.warn("userId={},clientId={},applyNo={} 没有确认记录", user.getUserId(),
                    user.getExternalClientId(), applyNo);
                continue;
            }

            HsTradeConfirmQryResponse tradeRecord = hsTradeList.get(0);

            if (tradeRecord == null || Strings.isNullOrEmpty(tradeRecord.getTaconfirm_flag())) {
                log.warn("trade confirm record is null, pass it");
                continue;
            }


            switch (tradeRecord.getTaconfirm_flag()) {
                case GlobalConstant.TACONFIRM_FLAG_CONFIRMED:
                    log.info("--->applyNo={},affirmDate={}", applyNo, tradeRecord.getAffirm_date());

                    // 更新状态

                    statusVo = TradeStatusVo.builder()
                        .tradeOrderId(tradeOrder.getOrderId())
                        .orderFundId(orderFund.getOrderFundId())
                        .build();

                    if (!Strings.isNullOrEmpty(tradeRecord.getAffirm_date())) {
                        statusVo.setConfirmDate(DateUtil.parse(tradeRecord.getAffirm_date(), HsConst.DATE_FORMAT_N8));
                    }

                    tradeService.updateTradeStatusSuc(statusVo);

                    try {
                        messageService.updateFundUserMsg(tradeOrder,orderFund,tradeRecord);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

//                        //获取tradeOrder的更新后数据
//                        tradeOrder = tradeOrderDao.getEntityByOrderId(orderFund.getOrderId());
//
//                        //event
//                        EventMsg eventMsg = new EventMsg();
//                        eventMsg.setConfirmDate(tradeOrder.getConfirmDate());
//                        eventMsg.setTradeType(tradeOrder.getTradeType());
//                        eventMsg.setUserId(user.getUserId());
//
//                        event = new BaseEvent();
//                        event.setEventType(EventTypeDef.TRADE_COMFIRM_SUC);
//                        event.setMessage(eventMsg);
//                        eventBusService.postAsync(event);

                    break;

                case GlobalConstant.TACONFIRM_FLAG_FAIL:
                    log.info("--->applyNo={},ta confirm fail", applyNo);

                    statusVo = TradeStatusVo.builder()
                        .tradeOrderId(tradeOrder.getOrderId())
                        .orderFundId(orderFund.getOrderFundId())
                        .build();

                    if (!Strings.isNullOrEmpty(tradeRecord.getAffirm_date())) {
                        statusVo.setConfirmDate(DateUtil.parse(tradeRecord.getAffirm_date(), HsConst.DATE_FORMAT_N8));
                    }

                    tradeService.updateTradeStatusFail(statusVo);
                    try {
                        messageService.updateFundFailUserMsg(tradeOrder,orderFund,tradeRecord);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;

                case GlobalConstant.TACONFIRM_FLAG_ACTION:
                case GlobalConstant.TACONFIRM_FLAG_PART_CONFIRMED:
                case GlobalConstant.TACONFIRM_FLAG_REAL_SUCCESS:
                    break;

                default:
                    log.warn("unprocessed ta confirm flag={}", tradeRecord.getTaconfirm_flag());
                    break;
            }

        }


        stopwatch.stop();

        log.info("sync common fund cost={}ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }


    private void syncPortfolioFund(Date beginCreateDate, Date endCreateDate) {
        log.info("sync portfolio fund status");
        Stopwatch stopwatch = Stopwatch.createStarted();

        PortfolioFundOrderQueryVo queryVo = PortfolioFundOrderQueryVo.builder()
                                                                     .status(GlobalConstant.FUND_STATUS_AWAITING_CONFIRM)
                                                                     .beginCreateDate(beginCreateDate)
                                                                     .endCreateDate(endCreateDate)
                                                                     .build();

        List<PortfolioFundOrder> fundOrders = portfolioFundOrderDao.query(queryVo);

        if (fundOrders == null || fundOrders.isEmpty()) {
            return;
        }


        Iterator<PortfolioFundOrder> iterator = fundOrders.iterator();

        while (iterator.hasNext()) {
            PortfolioFundOrder fundOrder = iterator.next();


            TradeOrder tradeOrder = tradeOrderDao.getEntityByOrderId(fundOrder.getOrderId());

            User user = userDao.getEntity(tradeOrder.getUserId());


            String applyNo = fundOrder.getExternalApplyNo();

            InnerCallback innerCallback = new InnerCallback() {
                @Override
                public void success(List<HsTradeConfirmQryResponse> hsTradeConfirmQryResponseList) {

                    HsTradeConfirmQryResponse tradeRecord = hsTradeConfirmQryResponseList.get(0);

                    log.info("--->applyNo={},affirmDate={}", applyNo, tradeRecord.getAffirm_date());

                    TradePortfolioStatusVo statusVo = TradePortfolioStatusVo.builder()
                                                                            .tradeOrderId(tradeOrder.getOrderId())
                                                                            .portfolioFundOrderId(fundOrder.getId())
                                                                            .build();
                    if (!Strings.isNullOrEmpty(tradeRecord.getAffirm_date())) {
                        statusVo.setConfirmDate(DateUtil.parse(tradeRecord.getAffirm_date(), HsConst.DATE_FORMAT_N8));
                    }

                    // 更新状态
                    portfolioService.updateTradeStatusSuc(statusVo);

                    try {
                        messageService.updatePortfolioFundUserMsg(tradeOrder,fundOrder,hsTradeConfirmQryResponseList);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
//                        //主要是获取confirmDate
//                        TradeOrder tradeOrder = tradeOrderDao.getEntityByOrderId(fundOrder.getOrderId());
//                        //event
//                        EventMsg eventMsg = new EventMsg();
//                        eventMsg.setConfirmDate(tradeOrder.getConfirmDate());
//                        eventMsg.setTradeType(tradeOrder.getTradeType());
//                        eventMsg.setUserId(user.getUserId());
//
//                    BaseEvent event = new BaseEvent();
//                    event.setEventType(EventTypeDef.TRADE_COMFIRM_SUC);
//                    event.setMessage(eventMsg);
//                    eventBusService.postAsync(event);
                }

                @Override
                public void fail(List<HsTradeConfirmQryResponse> hsTradeConfirmQryResponseList) {
                    log.info("--->applyNo={},ta confirm fail", applyNo);

                    if (ListUtil.isEmpty(hsTradeConfirmQryResponseList)) {
                        return;
                    }


                    HsTradeConfirmQryResponse tradeRecord = hsTradeConfirmQryResponseList.get(0);

                    TradePortfolioStatusVo statusVo = TradePortfolioStatusVo.builder()
                                                                            .tradeOrderId(tradeOrder.getOrderId())
                                                                            .portfolioFundOrderId(fundOrder.getId())
                                                                            .build();
                    if (!Strings.isNullOrEmpty(tradeRecord.getAffirm_date())) {
                        statusVo.setConfirmDate(DateUtil.parse(tradeRecord.getAffirm_date(), HsConst.DATE_FORMAT_N8));
                    }

                    portfolioService.updateTradeStatusFail(statusVo);

                    try {
                        messageService.updatePortfolioFundFailUserMsg(tradeOrder,fundOrder,hsTradeConfirmQryResponseList);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };

            try {
                syncAllFundInPortfolioStatus(
                    tradeOrder.getUserId(),
                    applyNo,
                    innerCallback);
            } catch (Exception e) {
                log.error("fail to sync all fund In portfolio status", e);
            }

        }


        stopwatch.stop();

        log.info("sync portfolio fund cost={}ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }

    private void syncPortfolioTransfer(Date beginCreateDate, Date endCreateDate) {
        log.info("sync portfolio transfer status");
        Stopwatch stopwatch = Stopwatch.createStarted();

        // 分页查询
        PortfolioFundOrderQueryVo queryVo = PortfolioFundOrderQueryVo.builder()
            .status(GlobalConstant.FUND_STATUS_AWAITING_CONFIRM)
            .beginCreateDate(beginCreateDate)
            .endCreateDate(endCreateDate)
            .build();

        List<FundPortfolioTransfer> portfolioTransfers = fundPortfolioTransferDao.query(queryVo);

        if (portfolioTransfers == null || portfolioTransfers.isEmpty()) {
            return;
        }


        Iterator<FundPortfolioTransfer> iterator = portfolioTransfers.iterator();

        while (iterator.hasNext()) {
            FundPortfolioTransfer portfolioTransfer = iterator.next();

            User user = userDao.getEntity(portfolioTransfer.getUserId());


            String applyNo = portfolioTransfer.getAllotNo();

            InnerCallback innerCallback = new InnerCallback() {
                @Override
                public void success(List<HsTradeConfirmQryResponse> hsTradeConfirmQryResponseList) {

                    HsTradeConfirmQryResponse tradeRecord = hsTradeConfirmQryResponseList.get(0);

                    log.info("--->applyNo={},affirmDate={}", applyNo, tradeRecord.getAffirm_date());

                    PortfolioTransferStatusVo statusVo = PortfolioTransferStatusVo.builder()
                        .id(portfolioTransfer.getId())
                        .build();
                    if (!Strings.isNullOrEmpty(tradeRecord.getAffirm_date())) {
                        statusVo.setConfirmDate(DateUtil.parse(tradeRecord.getAffirm_date(), HsConst.DATE_FORMAT_N8));
                    }

                    // 更新状态
                    portfolioTransferService.updateTransferStatusSuc(statusVo);

                    try {
                        messageService.updatePortfolioTransferUserMsg(portfolioTransfer);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void fail(List<HsTradeConfirmQryResponse> hsTradeConfirmQryResponseList) {
                    log.info("--->applyNo={},ta confirm fail", applyNo);

                    if (ListUtil.isEmpty(hsTradeConfirmQryResponseList)) {
                        return;
                    }


                    HsTradeConfirmQryResponse tradeRecord = hsTradeConfirmQryResponseList.get(0);

                    PortfolioTransferStatusVo statusVo = PortfolioTransferStatusVo.builder()
                        .id(portfolioTransfer.getId())
                        .build();
                    if (!Strings.isNullOrEmpty(tradeRecord.getAffirm_date())) {
                        statusVo.setConfirmDate(DateUtil.parse(tradeRecord.getAffirm_date(), HsConst.DATE_FORMAT_N8));
                    }

                    portfolioTransferService.updateTransferStatusFail(statusVo);

                    try {
                        messageService.updatePortfolioTransferFailUserMsg(portfolioTransfer);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };

            try {
                syncAllFundInPortfolioStatus(
                    portfolioTransfer.getUserId(),
                    applyNo,
                    innerCallback);
            } catch (Exception e) {
                log.error("fail to sync all fund In portfolio status", e);
            }

        }


        stopwatch.stop();

        log.info("sync portfolio fund cost={}ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }


    interface InnerCallback {
        void success(List<HsTradeConfirmQryResponse> hsTradeConfirmQryResponseList);

        void fail(List<HsTradeConfirmQryResponse> hsTradeConfirmQryResponseList);
    }


    private void syncAllFundInPortfolioStatus(Long userId,
                                              String portfolioAllotNo,
                                              InnerCallback callback) throws InterruptedException, ExecutionException {

        User user = userService.getUser(userId);

        String clientId = user.getExternalClientId();

        log.info("portfolio allotNo={}", portfolioAllotNo);

        PortfolioSummaryQryDto portfolioSummaryQryDto = PortfolioSummaryQryDto.builder()
                                                                              .portfolio_allot_no(portfolioAllotNo)
                                                                              .client_id(clientId)
                                                                              .request_num(50)
                                                                              .build();

        List<HsPortfolioSummaryQryResponse> summaryQryResponseList = hsPortfolioSummaryQryService.queryV2(portfolioSummaryQryDto);
        if (ListUtil.isEmpty(summaryQryResponseList)) {
            return;
        }
        HsPortfolioSummaryQryResponse portfolioSummaryQryResponse = summaryQryResponseList.get(0);

        String portfolioTradeAcco = portfolioSummaryQryResponse.getTrade_acco();


        TradeApplyQryDto tradeApplyQryDto = TradeApplyQryDto.builder()
                                                            .request_num(GlobalConstant.MAX_REQUEST_NUM.toString())
                                                            .trade_acco(portfolioTradeAcco)
                                                            .build();

        List<HsTradeApplyQryResponse> tradeApplyQryResponseList = tradeApplyQueryService.queryV2(tradeApplyQryDto);

        // check all
        List<String> allotNos = new ArrayList<>();

        for (int i = 0; i < tradeApplyQryResponseList.size(); i++) {
            HsTradeApplyQryResponse item = tradeApplyQryResponseList.get(i);

            if (EqualsUtil.equals(portfolioAllotNo, item.getPortfolio_allot_no())) {
                allotNos.add(item.getAllot_no());
            }
        }

        if (allotNos.isEmpty()) {
            return;
        }

        log.info("allotNos={} in portfolioAllotNo", allotNos);

        ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        final CompletionService<HsTradeConfirmQryResponse> completionService = new ExecutorCompletionService<>(exec);


        for (int i = 0; i < allotNos.size(); i++) {
            final String allotNo = allotNos.get(i);
            completionService.submit(() -> {
                HsTradeConfirmQryDto qryDto = HsTradeConfirmQryDto.builder()
                                                                  .client_id(clientId)
                                                                  .allot_no(allotNo)
                                                                  .trade_acco(portfolioTradeAcco)
                                                                  .build();

                List<HsTradeConfirmQryResponse> data = tradeConfirmQueryService.query(qryDto);

                if (ListUtil.isEmpty(data)) {
                    return null;
                }

                return data.get(0);
            });
        }

        int sucCount = 0, failCount = 0;
        List<HsTradeConfirmQryResponse> sucList = new ArrayList<>();
        List<HsTradeConfirmQryResponse> failedList = new ArrayList<>();

        for (int i = 0; i < allotNos.size(); i++) {
            Future<HsTradeConfirmQryResponse> future = completionService.take();
            HsTradeConfirmQryResponse tradeConfirmQryResponse = future.get();

            switch (tradeConfirmQryResponse.getTaconfirm_flag()) {
                case GlobalConstant.TACONFIRM_FLAG_CONFIRMED:
                    sucCount++;
                    sucList.add(tradeConfirmQryResponse);

                    break;
                case GlobalConstant.TACONFIRM_FLAG_FAIL:
                    failCount++;
                    failedList.add(tradeConfirmQryResponse);

                    break;
                case GlobalConstant.TACONFIRM_FLAG_ACTION:
                case GlobalConstant.TACONFIRM_FLAG_PART_CONFIRMED:
                case GlobalConstant.TACONFIRM_FLAG_REAL_SUCCESS:
                    break;

                default:
                    log.warn("unprocessed ta confirm flag={}", tradeConfirmQryResponse.getTaconfirm_flag());
                    break;
            }
        }

        if (sucCount == allotNos.size()) {
            log.info("buy portfolio successfully");

            if (callback != null) {
                callback.success(sucList);
            }
        }

        if (failCount >= 0) {
            log.info("fail to buy portfolio");

            if (callback != null) {
                callback.fail(failedList);
            }
        }

        exec.shutdown();
    }

    @Override
    public void syncDividend(Date beginCreateDate, Date endCreateDate){
        List<User> users = userDao.getAllUser();
        for (User user : users){
            log.info("sync dividend run time :{}, user:{}",beginCreateDate,user.getUserId());
            if (StringUtils.isBlank(user.getExternalClientId())){
                continue;
            }

            //查询分红记录
            HsDividendQryDto queryDto = HsDividendQryDto.builder()
                .client_id(user.getExternalClientId())
                .qry_beginrownum(1)
                .request_num(GlobalConstant.MAX_REQUEST_NUM)
                .sort_direction(HsConst.SORT_DIRECTION_DESC)
                .confirmdate_begin(DateUtils.formatDate4(beginCreateDate))
                .confirmdate_end(DateUtils.formatDate4(endCreateDate))
                .build();
            Map<String, Object> map = dividendsQueryService.queryDto(queryDto);
            //Map<String, Object> map = dividendsQueryService.query(GlobalConstant.MAX_REQUEST_NUM, 1, 1, "1", "", "", user.getExternalClientId(), "");
            List<Map<String, Object>> list = new ArrayList<>();
            AssetsResult result = new AssetsResult();
            HundsunUtils.ConvertToList(map, list, result);

            if (!result.getSuccess()) {
                throw new BaseException(result.getErrorCode(), result.getErrorMessage());
            }
            BaseListResult baseListResult = new BankListResult();
            List<DividendModel> dividends = ModelPopulateUtils.populateDividend(list, baseListResult);


            //插入消息表
            for (DividendModel dividendModel : dividends){
                try {
                    messageService.updateDividendUserMsg(dividendModel,user);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
//        LinkedBlockingQueue<User> queue = new LinkedBlockingQueue<>(50);
//        log.info("sync dividend begin time :{}",beginCreateDate);
//        new Thread() {
//            @Override
//            public void run() {
//                for (User user : users) {
//                    queue.offer(user);
//                }
//            }
//        }.start();
//
//        SyncDividendThread syncDividendThread = null;
//        try {
//            syncDividendThread = new SyncDividendThread(dividendsQueryService,messageService,lookupDao,beginCreateDate,endCreateDate,queue.take());
//
//        } catch (InterruptedException e) {
//            log.debug("线程异常");
//            e.printStackTrace();
//        }
//
//        ExecutorService executorService = Executors.newFixedThreadPool(10);
//
//        assert syncDividendThread != null;
//        executorService.submit(syncDividendThread);

    }

    @Override
    public void syncFix(Date beginCreateDate, Date endCreateDate){
        List<User> users = userDao.getAllUser();
        for (User user : users){
            if (StringUtils.isBlank(user.getExternalClientId())){
                continue;
            }
            log.info("sync fix run time :{}, user:{}",beginCreateDate,user.getUserId());

            //定投交易记录
            TradeApplyQryDto queryDto = TradeApplyQryDto.builder()
                .client_id(user.getExternalClientId())
                .qry_beginrownum("1")
                .request_num(GlobalConstant.MAX_REQUEST_NUM.toString())
                .fund_busin_code(GlobalConstant.FUND_BUSIN_CODE_APPLY_FIX_BUY)
                .sort_direction(HsConst.SORT_DIRECTION_DESC)
                .begin_date(DateUtils.formatDate4(beginCreateDate))
                .end_date(DateUtils.formatDate4(endCreateDate))
                .build();
            Map<String, Object> map = tradeApplyQueryService.query(queryDto);
            List<Map<String, Object>> list = new ArrayList<>();
            AssetsResult result = new AssetsResult();
            HundsunUtils.ConvertToList(map, list, result);

            if (!result.getSuccess()) {
                throw new BaseException(result.getErrorCode(), result.getErrorMessage());
            }
            ApplyListResult applyListResult = new ApplyListResult();
            List<ApplyModel> applyModels = ModelPopulateUtils.populateApply(list,applyListResult,null,null);
            // 获取T+0基金
            List<Lookup> lookups = lookupDao.getLookupByType(RuleConstant.RULE_LOOKUP_TYPE_T0FUND);

            //插入消息表
            for (ApplyModel applyModel : applyModels){
                log.debug("业务编码：{}",applyModel.getFundBusinCode());
                if (GlobalConstant.TACONFIRM_FLAG_CONFIRMED.equals(applyModel.getTAConfirmFlag())){
                    try {
                        messageService.updateFixUserMsg(applyModel,user,lookups);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }
    }




}
